package com.eco.websocket;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 木木羽田共
 * @datetime 2021/11/11 10:16
 * @description
 */
@ServerEndpoint("/eco/{userId}")
@Component
@Slf4j
public class WebSocketServer {

    public static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>(10);
    private Session session;
    private String userId;

    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     * @param userId  用户编号
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        log.info("websocket [{}] is open", userId);
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, this);
        } else {
            webSocketMap.put(userId, this);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        log.info("websocket [{}] is close", userId);
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param session
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        log.info("websocket [{}] send message:[{}]", userId, message);
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("websocket [{}] error:[{}]", userId, error.getMessage());
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
//            log.info("send message to websocket:[{}] success", userId);
        } catch (IOException e) {
            log.error("send message I/O exception:{}",e.toString());
        }
    }

    /**
     * 发送自定义消息
     */
    public static void sendInfo(String message, @PathParam("userId") String userId) {
        if (!StringUtils.isEmpty(userId) && webSocketMap.containsKey(userId)) {
            webSocketMap.get(userId).sendMessage(message);
        }
    }

    public static void sendInfo2All(String message) {
        for (String userId : webSocketMap.keySet())
        {
            webSocketMap.get(userId).sendMessage(message);
        }
    }

}
